using System.Collections;
using OfficeOpenXml;
using System.Reflection;
using net_work.Attribute;
using net_work.Common.Utils;
using net_work.IService.ISystem;

namespace net_work.Service.System
{
    public class ExcelExportService : IExcelExportService
    {
        public byte[] ExportToExcel<T>(IEnumerable<T> data)
        {
            using var package = new ExcelPackage();
            var worksheet = package.Workbook.Worksheets.Add("Export");

            // 获取所有属性并排序
            var properties = typeof(T).GetProperties()
                .Where(p => p.GetCustomAttribute<ExcelColumnAttribute>() != null)
                .OrderBy(p => p.GetCustomAttribute<ExcelColumnAttribute>().Order) // 排序列的顺序
                .ToList();

            // 设置表头
            for (var i = 0; i < properties.Count; i++)
            {
                var header = properties[i].GetCustomAttribute<ExcelColumnAttribute>()?.Header
                             ?? properties[i].Name; // 如果没有指定 Header，则使用属性名
                worksheet.Cells[1, i + 1].Value = header;
            }

            // 填充数据
            var dataList = data.ToList();
            for (var i = 0; i < dataList.Count; i++)
            {
                var row = dataList[i];
                for (var j = 0; j < properties.Count; j++)
                {
                    var value = GetPropertyValueRecursively(row, properties[j]);
                    worksheet.Cells[i + 2, j + 1].Value = value?.ToString();
                }
            }

            // 自动调整列宽
            worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();

            return package.GetAsByteArray();
        }


        private object? GetPropertyValueRecursively(object obj, PropertyInfo property)
        {
            var value = property.GetValue(obj);
            if (value == null)
            {
                return null;
            }
            
            var propertyType = property.PropertyType;
            
            if (propertyType == typeof(bool))
            {
                return ((bool)value) ? "是" : "否";
            }
            
            if (propertyType.IsPrimitive || propertyType == typeof(string))
            {
                return value;
            }

            if (propertyType.IsEnum)
            {
                return ((Enum)value).GetDescription();
            }

            if (propertyType == typeof(DateTime))
            {
                return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
            }

            if (typeof(IEnumerable).IsAssignableFrom(propertyType) && propertyType != typeof(string))
            {
                var enumerable = (IEnumerable)value;
                var elementType = propertyType.IsArray
                    ? propertyType.GetElementType()
                    : propertyType.GenericTypeArguments[0];
                if (elementType != null && (elementType.IsPrimitive || elementType == typeof(string)))
                {
                    return string.Join(", ", enumerable.Cast<object>());
                }

                // 对于元素是自定义类的情况，递归处理每个元素
                var result = (from object? element in enumerable
                        select GetPropertyValueRecursively(element, elementType.GetProperties().First()).ToString())
                    .ToList();

                return string.Join(", ", result);
            }

            {
                // 对于自定义类，递归获取其各个属性值并拼接
                var properties = propertyType.GetProperties();
                var result = properties
                    .Select(subProperty => GetPropertyValueRecursively(value, subProperty)?.ToString())
                    .ToList();

                return string.Join(", ", result);
            }
        }
    }
}